package com.xinqi.modules.chat.chat.chat.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.jiguang.common.utils.StringUtils;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.user.Account;
import com.xinqi.common.base.utils.json.JSON;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.common.mybatis.utils.Queries;
import com.xinqi.modules.chat.chat.chat.convert.ChatNoticeConvert;
import com.xinqi.modules.chat.chat.chat.domain.ChatNoticeEntity;
import com.xinqi.modules.chat.chat.chat.dto.req.ChatNoticeCreateDTO;
import com.xinqi.modules.chat.chat.chat.dto.rsp.ChatNoticeResultDTO;
import com.xinqi.modules.chat.chat.chat.mapper.ChatNoticeMapper;
import com.xinqi.modules.chat.chat.chat.service.ChatNoticeService;
import com.xinqi.modules.chat.chat.group.dto.rsp.ChatGroupUserResultDTO;
import com.xinqi.modules.chat.chat.group.service.ChatGroupUserService;
import com.xinqi.modules.chat.chat.group.service.impl.ChatGroupMessageService;
import com.xinqi.modules.chat.enums.notice.NoticeSendReteEnum;
import com.xinqi.modules.chat.favorite.controller.web.utils.LocalDateTimeUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 群公告记录表服务层实现
 *
 * @author: system
 * @date: 2023/01/12
 */
@Service("chatNoticeService")
@RequiredArgsConstructor
public class ChatNoticeServiceImpl extends BaseServiceImpl<ChatNoticeMapper, ChatNoticeEntity> implements ChatNoticeService {
    private final ChatNoticeConvert chatNoticeConvert;

    private final ChatGroupUserService chatGroupUserService;

    private final ChatGroupMessageService chatGroupMessageService;

    /**
     * 设置群公告 - 群主 - 管理
     *
     * @param dto ChatNoticeCreateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setGroupNotice(ChatNoticeCreateDTO dto, Account user) {
        //角色验证
        chatGroupUserService.checkAdministration(user.getId(), dto.getGroupId());
        //需要校验是否已存在群公告
        ChatNoticeEntity one = this.getOne(wrapper(dto.getGroupId()).last("LIMIT 1"));
        dto.setStatus(YesNoNumberEnum.YES.getCode());
        //是否定时发送和发送频率参数校验
        setGroupNoticeVerify(dto);
        boolean flag = Boolean.TRUE;
        if (Objects.isNull(one)) {
            CommonErrors.BAD_REQUEST.check(StringUtils.isNotEmpty(dto.getContent()), MessageUtils.message("chat.chat.notice.content.not.blank"));
            ChatNoticeEntity entity = chatNoticeConvert.create(dto);
            entity.setUserId(user.getId());
            flag = this.save(entity);
            if (flag) {
                //群组发布群公告小灰条通知消息
                chatGroupMessageService.sendNoticeMessage(user, dto.getGroupId(), dto.getContent());
            }
        } else {
            if (StringUtils.isEmpty(dto.getContent())) {
                //删除
                flag = this.deleteById(one.getId());
                if (flag) {
                    //群组取消群公告小灰条通知消息
                    chatGroupMessageService.sendCancelNoticeMessage(user, dto.getGroupId());
                }
            } else {
                //修改
                LambdaUpdateWrapper<ChatNoticeEntity> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(ChatNoticeEntity::getContent, dto.getContent())
                    .set(ChatNoticeEntity::getUserId, user.getId())
                    .set(ChatNoticeEntity::getReadUsers, StringUtil.EMPTY)
                    .set(ChatNoticeEntity::getStatus, dto.getStatus())
                    .set(ChatNoticeEntity::getTiming, dto.getTiming())
                    .set(ChatNoticeEntity::getIsRateSend, dto.getIsRateSend())
                    .set(ChatNoticeEntity::getSendRate, dto.getSendRate())
                    .set(ChatNoticeEntity::getSentTime, dto.getSentTime())
                    .set(ChatNoticeEntity::getJobTime, dto.getJobTime())
                    .set(ChatNoticeEntity::getCreateTime, LocalDateTime.now())
                    .set(ChatNoticeEntity::getCreateBy, user.getId())
                    .eq(ChatNoticeEntity::getId, one.getId());
                flag = this.update(updateWrapper);
                if (flag) {
                    //群组发布群公告小灰条通知消息
                    chatGroupMessageService.sendNoticeMessage(user, dto.getGroupId(), dto.getContent());
                }
            }
        }
        return flag;
    }

    /**
     * 查询群公告
     *
     * @param operationUserId
     * @param groupId         群主Id（融云）
     * @return
     */
    @Override
    public ChatNoticeResultDTO getGroupNoticeDetail(Long operationUserId, String groupId) {
        ChatNoticeResultDTO notice = this.baseMapper.getGroupNoticeDetail(groupId);
        if (Objects.isNull(notice)) {
            return null;
        }
        if (StringUtils.isEmpty(notice.getReadUsers())) {
            notice.setIsRead(YesNoNumberEnum.NO.getCode());
            return notice;
        }
        List<Long> userList = JSON.parseList(notice.getReadUsers(), Long.class);
        if (CollectionUtil.isEmpty(userList)) {
            notice.setIsRead(YesNoNumberEnum.NO.getCode());
            return notice;
        }
        if (userList.contains(operationUserId)) {
            notice.setIsRead(YesNoNumberEnum.YES.getCode());
        } else {
            notice.setIsRead(YesNoNumberEnum.NO.getCode());
        }

        return notice;
    }

    /**
     * 群公告 -- 阅读
     *
     * @param operationUserId Account
     * @param id              群公告Id
     * @return
     */
    @Override
    public Boolean setNoticeRead(Long operationUserId, Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), MessageUtils.message("chat.chat.notice.id.not.blank"));
        //获取公告阅读记录
        ChatNoticeEntity notice = this.baseMapper.selectById(id);
        String readUsers = notice.getReadUsers();
        List<Long> userList = null;
        if (StringUtils.isNotEmpty(readUsers)) {
            userList = JSON.parseList(readUsers, Long.class);
            if (userList != null && userList.size() > 0) {
                for (Long userId : userList) {
                    if (userId.equals(operationUserId)) {
                         return Boolean.TRUE;
                    }
                }
            }
        }
        if (CollectionUtil.isEmpty(userList)) {
            userList = new ArrayList<>();
        }
        //保存用户阅读记录
        userList.add(operationUserId);
        notice.setReadUsers(JSON.stringify(userList));
        return this.updateById(notice);
    }

    /**
     * 获取阅读成员列表
     *
     * @param id
     * @return
     */
    @DS("slaver")
    @Override
    public Map<String, List<ChatGroupUserResultDTO>> getNoticeReadUsers(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), MessageUtils.message("chat.chat.notice.id.not.blank"));
        //获取公告阅读记录
        ChatNoticeEntity notice = this.baseMapper.selectById(id);
        String readUsers = notice.getReadUsers();
        List<Long> userList;
        if (StringUtils.isNotEmpty(readUsers)) {
            userList = JSON.parseList(readUsers, Long.class);
        } else {
            userList = new ArrayList<>();
        }
        Map<String, List<ChatGroupUserResultDTO>> obj = new HashMap<>();
        //获取未阅读成员列表
        List<ChatGroupUserResultDTO> unreadList = chatGroupUserService.findReadUserList(userList, YesNoNumberEnum.NO.getCode());
        obj.put("unreadList", unreadList);
        //获取已阅读成员列表
        List<ChatGroupUserResultDTO> readList = chatGroupUserService.findReadUserList(userList, YesNoNumberEnum.YES.getCode());
        obj.put("readList", readList);
        return obj;
    }

    private LambdaQueryWrapper<ChatNoticeEntity> wrapper(String groupId) {
        LambdaQueryWrapper<ChatNoticeEntity> wrapper = Queries.lambda();
        Queries.accept(groupId, v -> wrapper.eq(ChatNoticeEntity::getGroupId, v));
        return wrapper;
    }

    private void setGroupNoticeVerify(ChatNoticeCreateDTO dto) {
        if (Objects.equals(YesNoNumberEnum.YES.getCode(), dto.getTiming())) {
            dto.setStatus(YesNoNumberEnum.NO.getCode());
            CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getJobTime()), MessageUtils.message("chat.chat.notice.jobTime.not.blank"));
        }
        if (Objects.equals(YesNoNumberEnum.YES.getCode(), dto.getIsRateSend())) {
            CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getSendRate()), MessageUtils.message("chat.chat.notice.sendRate.not.blank"));
            if (Objects.equals(NoticeSendReteEnum.ONE.getCode(), dto.getSendRate())) {
                dto.setSentTime(LocalDateTimeUtils.firstDayOfWeek(LocalDateTimeUtils.getDayStart()));
            }
            if (Objects.equals(NoticeSendReteEnum.TWO.getCode(), dto.getSendRate())) {
                dto.setSentTime(LocalDateTimeUtils.getDayStart());
            }
            if (Objects.equals(NoticeSendReteEnum.THREE.getCode(), dto.getSendRate())) {
                dto.setSentTime(LocalDateTimeUtils.lastDayOfMonth(LocalDateTimeUtils.getDayStart()));
            }
        }
    }

}
